﻿/*!
 *  Copyright (c), 上海沃恩信息科技有限公司.
 *  All rights reserved.
 *  Licensed under BSD (https://www.pittypat.work/bsd.html).
 */

using System.Threading.Tasks;
using Pittypat;

namespace Waln.Authority.Authentication
{
    /// <summary>
    /// 用户验证服务。
    /// </summary>
    public sealed class AuthorityService : IAuthorityService
    {
        private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(AuthorityService));

        private Api api;

        /// <summary>
        /// 初始化 AuthorityService 类的新实例。
        /// </summary>
        public AuthorityService()
        {
            this.api = new Api();
        }

        Task<string> IAuthorityService.GetSystemTokenAsync(string id, string key, IAsyncProgress progress)
        {
            return Task.FromResult("");
        }

        async Task<LoginResult> IAuthorityService.LoginAsync(string systemToken, string userName, string password, IAsyncProgress progress)
        {
            if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
            {
                return LoginResult.Anonymous;
            }

            var model = new FunctionModel<Args.Login>();
            model.Args.Name = userName;
            model.Args.Password = password;

            await this.api.LoginAsync(model, progress);

            if (!model.Success)
            {
                Log.Error(model.Message);
            }

            if (model.Success && model.Args.User != null && model.Args.User.Id.HasValue && !model.Args.Token.IsNullOrEmpty())
            {
                return new LoginResult(new AuthorityUser(model.Args.User), model.Args.Token.ToString());
            }

            return LoginResult.Anonymous;
        }

        async Task IAuthorityService.LogoutAsync(string systemToken, string userToken, IAsyncProgress progress)
        {
            if (!string.IsNullOrEmpty(userToken))
            {
                var model = new FunctionModel<Args.Logout>();
                model.Args.Token = (@binary)userToken;

                await this.api.LogoutAsync(model, progress);

                if (!model.Success)
                {
                    Log.Error(model.Message);
                }
            }
        }

        async Task<Permission> IAuthorityService.DemandAsync(string systemToken, string userToken, string funcPath, IAsyncProgress progress)
        {
            if (string.IsNullOrEmpty(userToken))
            {
                return null;
            }

            var model = new FunctionModel<Args.Demand>();
            model.Args.Token = (@binary)userToken;
            model.Args.Path = funcPath;

            await this.api.DemandAsync(model, progress);

            if (!model.Success)
            {
                Log.Error(model.Message);
            }

            if (!model.Success || model.Args.User == null)
            {
                return null;
            }

            return new Permission(new AuthorityUser(model.Args.User), model.Args.Authorized ?? false);
        }

        async Task<NavList> IAuthorityService.NavListAsync(string systemToken, string userToken, IAsyncProgress progress)
        {
            if (string.IsNullOrEmpty(userToken))
            {
                return NavList.Empty;
            }

            var model = new FunctionModel<Args.NavList>();
            model.Args.Token = (@binary)userToken;

            await this.api.NavListAsync(model, progress);

            if (!model.Success)
            {
                Log.Error(model.Message);
                return NavList.Empty;
            }

            return NavApp.ToNavApps(model.Args.Apps, model.Args.Modules);
        }
    }
}
